package com.admin.education.services.Implements;

import com.admin.education.common.exceptions.BadRequestException;
import com.admin.education.common.exceptions.ResourceNotFoundException;
import com.admin.education.dataTransferObject.PageRequest;
import com.admin.education.dataTransferObject.PageResponse;
import com.admin.education.dataTransferObject.ServicesExcuteResult;
import com.admin.education.dataTransferObject.user.LoginRequest;
import com.admin.education.dataTransferObject.user.Mapper.UserMapper;
import com.admin.education.dataTransferObject.user.Request.BindingInformationRequest;
import com.admin.education.dataTransferObject.user.Response.LoginResponse;
import com.admin.education.dataTransferObject.userAnswerSheet.Mapper.UserAnswerSheetMapper;
import com.admin.education.dataTransferObject.userAnswerSheet.UserAnswerSheetTransfer;
import com.admin.education.dataTransferObject.userInformation.Mapper.UserInformationMapper;
import com.admin.education.dataTransferObject.userInformation.UserInformationTransfer;
import com.admin.education.models.*;
import com.admin.education.repositories.*;
import com.admin.education.services.Interfaces.IUserService;
import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.transaction.Transactional;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
@Validated
public class UserService implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserInformationMapper userInformationMapper;
    @Autowired
    private UserAnswerSheetMapper userAnswerSheetMapper;
    @Autowired
    private UserRepository usersRepository;
    private QUser qUser;
    private QUserAnswerSheet qUserAnswerSheet;
    private QUserInformation qUserInformation;
    private QAttentionAndFans qAttentionAndFans;

    @Autowired
    private UserInformationRepository userInformationRepository;
    @Autowired
    private UserAnswerSheetRepository userAnswerSheetRepository;
    @Autowired
    private AttentionAndFansRepository attentionAndFansRepository;

    public UserService() {
        qUser = QUser.user;
        qUserAnswerSheet = QUserAnswerSheet.userAnswerSheet;
        qUserInformation = QUserInformation.userInformation;
        qAttentionAndFans = QAttentionAndFans.attentionAndFans;
    }

    @Override
    public ServicesExcuteResult<LoginResponse> Login(@Valid LoginRequest loginRequest) throws ResourceNotFoundException {
        ServicesExcuteResult<LoginResponse> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<User> userQuery = usersRepository.selectFrom(qUser).where(qUser.userName.eq(loginRequest.getUsername()));
        if (userQuery.fetchCount() != 0) {
            userQuery = userQuery.where(qUser.password.eq(loginRequest.getPassword()));
            if (0 != userQuery.fetchCount()) {
                servicesExcuteResult.setSuccess(true);
                servicesExcuteResult.setData(new LoginResponse(userQuery.fetchFirst().getId()));
            } else {
                servicesExcuteResult.setErrorMessage("密码不正确");
            }
        } else {
            throw new ResourceNotFoundException("用户不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult Binding(long userId, @Valid BindingInformationRequest bindingInformationRequest) throws BadRequestException, ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();
        JPAQuery<User> userJPAQuery = this.usersRepository.selectFrom(qUser).where(qUser.id.eq(userId));
        if (0 != userJPAQuery.fetchCount()) {
            User user = userJPAQuery.fetchOne();
            UserInformation userInformation = userMapper.mapFrom(bindingInformationRequest);

            userInformation.setValid(true);
            userInformation.setStatus(UserInformation.UserInformationStatus.WaitAudit);

            user.getUserInformation().add(userInformation);
            userInformation.setUser(user);
            this.usersRepository.merge(user);
            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("用户不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<List<UserInformationTransfer>> QueryUserInformations(long userId) throws ResourceNotFoundException {
        ServicesExcuteResult<List<UserInformationTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<User> userJPAQuery = this.usersRepository.selectFrom(qUser).where(qUser.id.eq(userId));
        if (0 != userJPAQuery.fetchCount()) {
            User user = userJPAQuery.fetchOne();
            servicesExcuteResult.setData(userInformationMapper.mapFrom(user.getUserInformation().stream().filter(p -> p.isValid()).collect(Collectors.toList())));

            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("用户不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<UserInformationTransfer> ChangeAuth(long userId, long userInformationId) throws BadRequestException, ResourceNotFoundException {
        ServicesExcuteResult<UserInformationTransfer> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<User> userJPAQuery = this.usersRepository.selectFrom(qUser).where(qUser.id.eq(userId));
        if (0 != userJPAQuery.fetchCount()) {
            User user = userJPAQuery.fetchOne();
            Optional<UserInformation> userInformationOptional = user.getUserInformation().stream().filter(p -> p.isValid() && p.getId() == userInformationId).findAny();
            if (!userInformationOptional.isPresent()) {
                servicesExcuteResult.setErrorMessage("不存在该权限");
            } else {
                UserInformation userInformation = userInformationOptional.get();
                if (!userInformation.checkStatus()) {
                    servicesExcuteResult.setErrorMessage("状态不正确");
                }
                userInformation.setLastLoginTime(new Date());
                userInformationRepository.merge(userInformation);

                servicesExcuteResult.setData(userInformationMapper.mapFrom(userInformation));
                servicesExcuteResult.setErrorMessage(user.getOpenId());
                servicesExcuteResult.setSuccess(true);
            }

        } else {
            throw new ResourceNotFoundException("用户不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<User> GetUser(@NotBlank String openId) throws ResourceNotFoundException {
        ServicesExcuteResult<User> servicesExcuteResult = new ServicesExcuteResult<>();

        JPAQuery<User> userJPAQuery = this.usersRepository.selectFrom(qUser).where(qUser.openId.eq(openId));
        if (0 != userJPAQuery.fetchCount()) {
            User user = userJPAQuery.fetchOne();
            servicesExcuteResult.setData(user);
            servicesExcuteResult.setSuccess(true);

        } else {
            throw new ResourceNotFoundException("用户不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<PageResponse<UserAnswerSheetTransfer>> queryUserAnswerSheetByUserId(long userInformationId, @NotNull @Valid PageRequest pageRequest) {
        ServicesExcuteResult<PageResponse<UserAnswerSheetTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();

        JPAQuery<UserAnswerSheet> userAnswerSheetJPAQuery = this.userAnswerSheetRepository.selectFrom(qUserAnswerSheet).where(qUserAnswerSheet.userInformation.id.eq(userInformationId));

        long totalCount = userAnswerSheetJPAQuery.fetchCount();

        userAnswerSheetJPAQuery = userAnswerSheetJPAQuery.orderBy(qUserAnswerSheet.createTime.asc()).offset((pageRequest.getPageIndex() - 1) * pageRequest.getPageSize()).limit(pageRequest.getPageSize());

        List<UserAnswerSheet> userAnswerSheets = userAnswerSheetJPAQuery.fetch();

        List<UserAnswerSheetTransfer> userAnswerSheetTransfers = userAnswerSheetMapper.mapFrom(userAnswerSheets);

        PageResponse<UserAnswerSheetTransfer> userAnswerSheetTransferPageResponse = new PageResponse<>(pageRequest.getPageSize(), pageRequest.getPageIndex(), (int) totalCount, userAnswerSheetTransfers);

        servicesExcuteResult.setData(userAnswerSheetTransferPageResponse);
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult attentionSomeOne(long userInformationId, long fansId) throws ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();

        if (fansId == userInformationId) {
            servicesExcuteResult.setErrorMessage("自己不能关注自己");
            return servicesExcuteResult;
        }

        JPAQuery<AttentionAndFans> attentionAndFansJPAQuery = this.attentionAndFansRepository.selectFrom(qAttentionAndFans).where(qAttentionAndFans.attention.id.eq(userInformationId).and(qAttentionAndFans.fan.id.eq(fansId)));

        if (0 != attentionAndFansJPAQuery.fetchCount()) {
            servicesExcuteResult.setErrorMessage("不用重复设置");
            return servicesExcuteResult;
        }

        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId));
        JPAQuery<UserInformation> fansJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(fansId));

        if (0 != userInformationJPAQuery.fetchCount() && 0 != fansJPAQuery.fetchCount()) {
            UserInformation userInformation = userInformationJPAQuery.fetchOne();
            UserInformation fans = fansJPAQuery.fetchFirst();

            AttentionAndFans attentionAndFans = new AttentionAndFans();
            attentionAndFans.setAttention(userInformation);
            attentionAndFans.setFan(fans);

            this.attentionAndFansRepository.persist(attentionAndFans);

            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("用户不存在!");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult cancelAttentionSomeOne(long userInformationId, long fansId) throws ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();

        if (fansId == userInformationId) {
            servicesExcuteResult.setErrorMessage("自己不能取消关注自己");
            return servicesExcuteResult;
        }

        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId));
        JPAQuery<UserInformation> fansJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(fansId));

        if (0 != userInformationJPAQuery.fetchCount() && 0 != fansJPAQuery.fetchCount()) {

            JPAQuery<AttentionAndFans> attentionAndFansJPAQuery = this.attentionAndFansRepository.selectFrom(qAttentionAndFans).where(qAttentionAndFans.attention.id.eq(userInformationId), qAttentionAndFans.fan.id.eq(fansId));

            if (0 != attentionAndFansJPAQuery.fetchCount()) {
                AttentionAndFans attentionAndFans = attentionAndFansJPAQuery.fetchFirst();

                this.attentionAndFansRepository.remove(attentionAndFans);
                servicesExcuteResult.setSuccess(true);
            } else {
                servicesExcuteResult.setErrorMessage("没有关注该用户");
            }
        } else {
            throw new ResourceNotFoundException("用户不存在!");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<Boolean> queryAttentsion(long userInformationId, long fansId) throws ResourceNotFoundException {
        ServicesExcuteResult<Boolean> servicesExcuteResult = new ServicesExcuteResult();

        if (fansId == userInformationId) {
            servicesExcuteResult.setErrorMessage("自己不能查询自己");
            return servicesExcuteResult;
        }

        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId));
        JPAQuery<UserInformation> fansJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(fansId));

        if (0 != userInformationJPAQuery.fetchCount() && 0 != fansJPAQuery.fetchCount()) {

            JPAQuery<AttentionAndFans> attentionAndFansJPAQuery = this.attentionAndFansRepository.selectFrom(qAttentionAndFans).where(qAttentionAndFans.attention.id.eq(userInformationId), qAttentionAndFans.fan.id.eq(fansId));

            if (0 != attentionAndFansJPAQuery.fetchCount()) {
                servicesExcuteResult.setData(true);
                servicesExcuteResult.setSuccess(true);
            } else {
                servicesExcuteResult.setData(false);
            }
        } else {
            throw new ResourceNotFoundException("用户不存在!");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<UserInformationTransfer> getCurrentInformation(long userInformationId) throws ResourceNotFoundException {
        ServicesExcuteResult<UserInformationTransfer> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId));

        if (0 != userInformationJPAQuery.fetchCount()) {
            UserInformation userInformation = userInformationJPAQuery.fetchOne();
            servicesExcuteResult.setData(userInformationMapper.mapFrom(userInformation));
            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("用户不存在!");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<PageResponse<UserInformationTransfer>> getAttentions(long userInformationId, @Valid PageRequest pageRequest) {
        ServicesExcuteResult<PageResponse<UserInformationTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<AttentionAndFans> attentionAndFansJPAQuery = this.attentionAndFansRepository.selectFrom(qAttentionAndFans).where(qAttentionAndFans.attention.id.eq(userInformationId));

        long totalCount = attentionAndFansJPAQuery.fetchCount();

        attentionAndFansJPAQuery = attentionAndFansJPAQuery.orderBy(qAttentionAndFans.id.asc())
                .offset((pageRequest.getPageIndex() - 1) * pageRequest.getPageSize()).limit(pageRequest.getPageSize());

        List<AttentionAndFans> attentionAndFans = attentionAndFansJPAQuery.fetch();

        List<UserInformation> userInformations = new ArrayList<>();

        for (AttentionAndFans attentionAndFan : attentionAndFans) {
            userInformations.add(attentionAndFan.getFan());
        }

        List<UserInformationTransfer> userInformationTransfers = userInformationMapper.mapFrom(userInformations);
        PageResponse<UserInformationTransfer> userInformationTransferPageResponse = new PageResponse<>(pageRequest.getPageSize(), pageRequest.getPageIndex(), (int) totalCount, userInformationTransfers);
        servicesExcuteResult.setData(userInformationTransferPageResponse);
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<PageResponse<UserInformationTransfer>> getFans(long userInformationId, @Valid PageRequest pageRequest) {
        ServicesExcuteResult<PageResponse<UserInformationTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();
        JPAQuery<AttentionAndFans> attentionAndFansJPAQuery = this.attentionAndFansRepository.selectFrom(qAttentionAndFans).where(qAttentionAndFans.fan.id.eq(userInformationId));

        long totalCount = attentionAndFansJPAQuery.fetchCount();

        attentionAndFansJPAQuery = attentionAndFansJPAQuery.orderBy(qAttentionAndFans.id.asc())
                .offset((pageRequest.getPageIndex() - 1) * pageRequest.getPageSize()).limit(pageRequest.getPageSize());

        List<AttentionAndFans> attentionAndFans = attentionAndFansJPAQuery.fetch();

        List<UserInformation> userInformations = new ArrayList<>();

        for (AttentionAndFans attentionAndFan : attentionAndFans) {
            userInformations.add(attentionAndFan.getAttention());
        }

        List<UserInformationTransfer> userInformationTransfers = userInformationMapper.mapFrom(userInformations);
        PageResponse<UserInformationTransfer> userInformationTransferPageResponse = new PageResponse<>(pageRequest.getPageSize(), pageRequest.getPageIndex(), (int) totalCount, userInformationTransfers);
        servicesExcuteResult.setData(userInformationTransferPageResponse);
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

}